
#import "NSString+XBKit.h"

@implementation NSString (XBKit)

#pragma +++++++++++++++++++++++类方法++++++++++++++++++++

+ (void)nslogPropertyWithDic:(NSDictionary *)dic {
    
    if (![dic isKindOfClass:[NSDictionary class]]) {
        NSLog(@"无法解析为model，因为传入参数不是一个字典");
        return;
    }
    
    if (dic.count == 0) {
        NSLog(@"无法解析为model，因为该字典为空");
        return;
    }
    
    
    NSMutableString *strM = [NSMutableString string];
    [dic enumerateKeysAndObjectsUsingBlock:^(id key, id obj, BOOL *stop) {
        
        NSString *className = NSStringFromClass([obj class]) ;
        NSLog(@"className:%@/n", className);
        if ([className isEqualToString:@"__NSCFString"] | [className isEqualToString:@"__NSCFConstantString"] | [className isEqualToString:@"NSTaggedPointerString"]) {
            [strM appendFormat:@"@property (nonatomic, copy) NSString *%@;\n",key];
        }else if ([className isEqualToString:@"__NSCFArray"] |
                  [className isEqualToString:@"__NSArray0"] |
                  [className isEqualToString:@"__NSArrayI"]){
            [strM appendFormat:@"@property (nonatomic, strong) NSArray *%@;\n",key];
        }else if ([className isEqualToString:@"__NSCFDictionary"]){
            [strM appendFormat:@"@property (nonatomic, strong) NSDictionary *%@;\n",key];
        }else if ([className isEqualToString:@"__NSCFNumber"]){
            [strM appendFormat:@"@property (nonatomic, copy) NSNumber *%@;\n",key];
        }else if ([className isEqualToString:@"__NSCFBoolean"]){
            [strM appendFormat:@"@property (nonatomic, assign) BOOL   %@;\n",key];
        }else if ([className isEqualToString:@"NSDecimalNumber"]){
            [strM appendFormat:@"@property (nonatomic, copy) NSString *%@;\n",[NSString stringWithFormat:@"%@",key]];
        }
        else if ([className isEqualToString:@"NSNull"]){
            [strM appendFormat:@"@property (nonatomic, copy) NSString *%@;\n",[NSString stringWithFormat:@"%@",key]];
        }else if ([className isEqualToString:@"__NSArrayM"]){
            [strM appendFormat:@"@property (nonatomic, strong) NSMutableArray *%@;\n",[NSString stringWithFormat:@"%@",key]];
        }
        
    }];
    NSLog(@"\n%@\n",strM);
}


+(BOOL)isBlankString:(NSString *)string{
    
    NSString *toString = [NSString stringWithFormat:@"%@",string];
    if (toString == nil || toString == NULL) {
        return YES;
    }
    
    if ([toString isKindOfClass:[NSNull class]]) {
        return YES;
    }
    
    if ([toString isEqualToString:@""]) {
        return YES;
    }
    
    if ([toString isEqualToString:@"(null)"]) {
        return YES;
    }
    
    if ([toString isEqualToString:@"null"]) {
        return YES;
    }
    
    if ([toString isEqualToString:@"<null>"]) {
        return YES;
    }
    
    if ([toString stringByReplacingOccurrencesOfString:@" " withString:@""].length<=0) {
        return YES;
    }
    
    return NO;
}


/**
 *  判断字符串是否是银行卡
 *
 *  @return YES 正确/ NO 不正确
 */
+ (BOOL)isCheckCardNo:(NSString*)cardNo{
    
    int oddsum = 0;     //奇数求和
    int evensum = 0;    //偶数求和
    int allsum = 0;
    int cardNoLength = (int)[cardNo length];
    int lastNum = [[cardNo substringFromIndex:cardNoLength-1] intValue];
    
    cardNo = [cardNo substringToIndex:cardNoLength - 1];
    for (int i = cardNoLength -1 ; i>=1;i--) {
        NSString *tmpString = [cardNo substringWithRange:NSMakeRange(i-1, 1)];
        int tmpVal = [tmpString intValue];
        if (cardNoLength % 2 ==1 ) {
            if((i % 2) == 0){
                tmpVal *= 2;
                if(tmpVal>=10)
                    tmpVal -= 9;
                evensum += tmpVal;
            }else{
                oddsum += tmpVal;
            }
        }else{
            if((i % 2) == 1){
                tmpVal *= 2;
                if(tmpVal>=10)
                    tmpVal -= 9;
                evensum += tmpVal;
            }else{
                oddsum += tmpVal;
            }
        }
    }
    
    allsum = oddsum + evensum;
    allsum += lastNum;
    if((allsum % 10) == 0){
        return YES;
    }else{
        return NO;
    }
    
}

#pragma ================================金融类处理小数输入小数========================

+ (NSString *)notRounding:(NSString *)price afterPoint:(NSInteger)position{
    
    //保留小数点后两位
    //NSRoundDown   下舍入 
    NSDecimalNumberHandler*roundUp = [NSDecimalNumberHandler
                                      
                                      decimalNumberHandlerWithRoundingMode:NSRoundBankers
                                      
                                      scale:2
                                      
                                      raiseOnExactness:NO
                                      
                                      raiseOnOverflow:NO
                                      
                                      raiseOnUnderflow:NO
                                      
                                      raiseOnDivideByZero:YES];
    
    NSDecimalNumber*subtotal = [NSDecimalNumber decimalNumberWithString:price];
    
    
    NSDecimalNumber * roundedOunces = [subtotal decimalNumberByRoundingAccordingToBehavior:roundUp];
    
    //NSLog(@"保留小数点后两位%lf",[roundedOunces doubleValue]);
    
    return [NSString stringWithFormat:@"%.2lf",[roundedOunces doubleValue]];
}

+ (NSString *)notRounding2:(NSString *)price{
    
    
    return  [[self class] notRounding:price afterPoint:2];
}

+ (BOOL)LimitUITextFieldUITextField:(NSString *)string
                         Tobestring:(NSString *)toBeSting
                            maxBiggest:(NSInteger)maxBiggest

{
    
    NSCharacterSet *cs = [[NSCharacterSet characterSetWithCharactersInString:@"0123456789\n"]invertedSet];
    NSString *filtered = [[string componentsSeparatedByCharactersInSet:cs]componentsJoinedByString:@""];
    //按cs分离出数组,数组按@""分离出字符串
    BOOL canChange = [string isEqualToString:filtered];
    if (canChange) {
        //判断首字符不为0
        if ([toBeSting hasPrefix:@"0"]) {
            canChange=NO;
            
        }else{
            
            if (maxBiggest == 0) {
                
                canChange = YES;
                
            }else{
                if (toBeSting.length >maxBiggest) {
                    
                    canChange=NO;
                    
                }else{
                    
                    canChange=YES;
                }
            }
        }
    }
    return canChange;
}
/*
string-----正在输入的字符
cString----正确的输入字符集
toBeSting--输入框内的所有字符
dpB--------小数点前几位
dpA--------小数点后几位
     
NSString * toBeString = [textField.text stringByReplacingCharactersInRange:range withString:string];
     
BOOL canChange=[nsstring DigitalUITextFieldUITextField:string Characterset:@".0123456789\n" Tobestring:toBeString Decimalpoint_Before:8 Decimalpoint_After:2];
     
*/
+ (BOOL)LimitUITextFieldUITextField:(NSString *)string
                       Characterset:(NSString *)cString
                           Tobestring:(NSString *)toBeSting Decimalpoint_Before:(NSInteger)dPB
                   Decimalpoint_After:(NSInteger)dPA{
    
    NSCharacterSet *cs = [[NSCharacterSet characterSetWithCharactersInString:cString]invertedSet];
    NSString *filtered = [[string componentsSeparatedByCharactersInSet:cs]componentsJoinedByString:@""];
    //按cs分离出数组,数组按@""分离出字符串
    BOOL canChange = [string isEqualToString:filtered];
    if (canChange) {
        //判断[.]字符集的个数
        NSString *regExStr = @"[.]";
        NSError *error = NULL;
        NSRegularExpression *regex = [NSRegularExpression regularExpressionWithPattern:regExStr options:NSRegularExpressionCaseInsensitive error:&error];
        NSUInteger numberOfMatches = [regex numberOfMatchesInString:toBeSting options:0 range:NSMakeRange(0, [toBeSting length])];
        
        if (numberOfMatches>=2) {
            
            canChange=NO;
            
        }else{
            //判断首字符不为.
            if ([toBeSting hasPrefix:@"."]) {
                canChange=NO;
                
            }else{
                //判断有无小数点，，有则判读小数点后6位，无则前四位
                if(numberOfMatches>=1){
                    
                    NSArray *array=[toBeSting componentsSeparatedByString:@"."];
                    if ([[array objectAtIndex:1] length] >dPA) {
                        canChange=NO;
                    }
                }else{
                    
                    
                    if ([toBeSting hasPrefix:@"0"]&&toBeSting.length >= 2) {
                        
                        //NSLog(@"%@",toBeSting);
                        
                        NSString *string2 = [toBeSting substringWithRange:NSMakeRange(1, 1)];
                        
                        //NSLog(@"%@",string2);
                        
                        if([string2 isEqualToString:@"."]||[string isEqualToString:@""]){
                            
                            canChange = YES;
                        }else{
                            
                            canChange=NO;
                        }
                        
                    }else if([toBeSting length] >dPB) {
                        
                        canChange=NO;
                    }
                    
                    
                }
            }
        }
    }
    return canChange;
    
}
+ (BOOL)LimitUITextView:(UITextView *)textView shouldChangeTextInRange:(NSRange)range replacementText:(NSString *)text isEmoji:(BOOL)isEmoji  maxLimitNums:(NSInteger)maxLimitNums{
    
    ///禁用emoji 表情
    if(isEmoji){
        
        //禁止输入emoji表情
        if ([text stringContainsEmoji]) {
            return NO;
        }
        
    }
    
    
    UITextRange *selectedRange = [textView markedTextRange];
    //获取高亮部分
    UITextPosition *pos = [textView positionFromPosition:selectedRange.start offset:0];
    //获取高亮部分内容
    //NSString * selectedtext = [textView textInRange:selectedRange];
    
    //如果有高亮且当前字数开始位置小于最大限制时允许输入
    if (selectedRange && pos) {
        NSInteger startOffset = [textView offsetFromPosition:textView.beginningOfDocument toPosition:selectedRange.start];
        NSInteger endOffset = [textView offsetFromPosition:textView.beginningOfDocument toPosition:selectedRange.end];
        NSRange offsetRange = NSMakeRange(startOffset, endOffset - startOffset);
        
        if (offsetRange.location < maxLimitNums) {
            return YES;
        }
        else
        {
            return NO;
        }
    }
    
    
    NSString *comcatstr = [textView.text stringByReplacingCharactersInRange:range withString:text];
    
    NSInteger caninputlen = maxLimitNums - comcatstr.length;
    
    if (caninputlen >= 0)
    {
        return YES;
    }
    else
    {
        NSInteger len = text.length + caninputlen;
        //防止当text.length + caninputlen < 0时，使得rg.length为一个非法最大正数出错
        NSRange rg = {0,MAX(len,0)};
        
        if (rg.length > 0)
        {
            NSString *s = @"";
            //判断是否只普通的字符或asc码(对于中文和表情返回NO)
            BOOL asc = [text canBeConvertedToEncoding:NSASCIIStringEncoding];
            if (asc) {
                s = [text substringWithRange:rg];//因为是ascii码直接取就可以了不会错
            }
            else
            {
                __block NSInteger idx = 0;
                __block NSString  *trimString = @"";//截取出的字串
                //使用字符串遍历，这个方法能准确知道每个emoji是占一个unicode还是两个
                [text enumerateSubstringsInRange:NSMakeRange(0, [text length])
                                         options:NSStringEnumerationByComposedCharacterSequences
                                      usingBlock: ^(NSString* substring, NSRange substringRange, NSRange enclosingRange, BOOL* stop) {
                                          
                                          if (idx >= rg.length) {
                                              *stop = YES; //取出所需要就break，提高效率
                                              return ;
                                          }
                                          
                                          trimString = [trimString stringByAppendingString:substring];
                                          
                                          idx++;
                                      }];
                
                s = trimString;
            }
            //rang是指从当前光标处进行替换处理(注意如果执行此句后面返回的是YES会触发didchange事件)
            [textView setText:[textView.text stringByReplacingCharactersInRange:range withString:s]];
            //既然是超出部分截取了，哪一定是最大限制了。
            //self.UserCoutomer.text = [NSString stringWithFormat:@"%d/%ld",0,(long)MAX_LIMIT_NUMS];
        }
        return NO;
    }
    
    return YES;
}
#pragma  +++++++++++++++++++++++实列方法++++++++++++++++++++

- (CGSize)sizeWithFont:(UIFont *)font maxW:(CGFloat)maxW
{
    NSMutableDictionary *attrs = [NSMutableDictionary dictionary];
    attrs[NSFontAttributeName] = font;
    CGSize maxSize = CGSizeMake(maxW, MAXFLOAT);
    return [self boundingRectWithSize:maxSize options:NSStringDrawingUsesLineFragmentOrigin |NSStringDrawingUsesFontLeading attributes:attrs context:nil].size;
}

- (CGSize)sizeWithFont:(UIFont *)font
{
    return [self sizeWithFont:font maxW:MAXFLOAT];
    
    
}
- (CGSize)sizeWithFont:(UIFont *)font andMaxW:(CGFloat)maxW
{
    return [self sizeWithFont:font maxW:maxW];
    
    
}


#pragma =========================验证=========================
/**
 *      是不是中文
 */
-(BOOL)isChinese{
    
    for(int i=0; i< [self length];i++){
        
        int a = [self characterAtIndex:i];
        if( a > 0x4e00 && a < 0x9fff){
            
            return YES;
            
        }
    }
    return NO;
    
}
/**
 *  判断是否是手机号  能同时验证 +86 86 或无 86开头的手机号
 *
 *  @return YES 正确/ NO 不正确
 */
- (BOOL)isPhone{
    
    NSString * PHS = @"^((\\+86)|(86))?(1[0-9])\\d{9}$";
    NSPredicate *TalTest = [NSPredicate predicateWithFormat:@"SELF MATCHES%@",PHS];
    return [TalTest evaluateWithObject:self];
    
}
/**
 *  是否是邮箱
 *
 *  @return YES 正确 / NO 不正确
 */
- (BOOL)isEmail{
    
    NSString * PHS = @"^([a-zA-Z0-9_\\-\\.]+)@((\\[[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}\\.)|(([a-zA-Z0-9\\-]+\\.)+))([a-zA-Z]{2,4}|[0-9]{1,3})(\\]?)$";
    NSPredicate *TalTest = [NSPredicate predicateWithFormat:@"SELF MATCHES%@",PHS];
    return [TalTest evaluateWithObject:self];
    
}

/**
 *  检查密码否和规定吗  正则匹配用户密码6-20位数字和字母组合
 *
 *  @return
 */
- (BOOL)isCheckPassword{
    
    
    return YES;
}

- (BOOL)isIDCardNumber{
    
    BOOL flag;
    if (self.length <= 0)
    {
        flag = NO;
        return flag;
    }
    
    NSString *regex2 = @"^(^[1-9]\\d{7}((0\\d)|(1[0-2]))(([0|1|2]\\d)|3[0-1])\\d{3}$)|(^[1-9]\\d{5}[1-9]\\d{3}((0\\d)|(1[0-2]))(([0|1|2]\\d)|3[0-1])((\\d{4})|\\d{3}[Xx])$)$";
    NSPredicate *selfPredicate = [NSPredicate predicateWithFormat:@"SELF MATCHES %@",regex2];
    flag = [selfPredicate evaluateWithObject:self];
    
    
    //如果通过该验证，说明身份证格式正确，但准确性还需计算
    if(flag)
    {
        if(self.length==18)
        {
            //将前17位加权因子保存在数组里
            NSArray * idCardWiArray = @[@"7", @"9", @"10", @"5", @"8", @"4", @"2", @"1", @"6", @"3", @"7", @"9", @"10", @"5", @"8", @"4", @"2"];
            
            //这是除以11后，可能产生的11位余数、验证码，也保存成数组
            NSArray * idCardYArray = @[@"1", @"0", @"10", @"9", @"8", @"7", @"6", @"5", @"4", @"3", @"2"];
            
            //用来保存前17位各自乖以加权因子后的总和
            
            NSInteger idCardWiSum = 0;
            for(int i = 0;i < 17;i++)
            {
                NSInteger subStrIndex = [[self substringWithRange:NSMakeRange(i, 1)] integerValue];
                NSInteger idCardWiIndex = [[idCardWiArray objectAtIndex:i] integerValue];
                
                idCardWiSum+= subStrIndex * idCardWiIndex;
                
            }
            
            //计算出校验码所在数组的位置
            NSInteger idCardMod=idCardWiSum%11;
            
            //得到最后一位身份证号码
            NSString * idCardLast= [self substringWithRange:NSMakeRange(17, 1)];
            
            //如果等于2，则说明校验码是10，身份证号码最后一位应该是X
            if(idCardMod==2)
            {
                if([idCardLast isEqualToString:@"X"]||[idCardLast isEqualToString:@"x"])
                {
                    return flag;
                }else
                {
                    flag =  NO;
                    return flag;
                }
            }else
            {
                //用计算出的验证码与最后一位身份证号码匹配，如果一致，说明通过，否则是无效的身份证号码
                if([idCardLast isEqualToString: [idCardYArray objectAtIndex:idCardMod]])
                {
                    return flag;
                }
                else
                {
                    flag =  NO;
                    return flag;
                }
            }
        }
        else
        {
            flag =  NO;
            return flag;
        }
    }
    else
    {
        return flag;
    }
}

//判断是否输入了emoji 表情
- (BOOL)stringContainsEmoji
{
    __block BOOL returnValue = NO;
    
    [self enumerateSubstringsInRange:NSMakeRange(0, [self length])
                             options:NSStringEnumerationByComposedCharacterSequences
                          usingBlock:^(NSString *substring, NSRange substringRange, NSRange enclosingRange, BOOL *stop) {
                              const unichar hs = [substring characterAtIndex:0];
                              if (0xd800 <= hs && hs <= 0xdbff) {
                                  if (substring.length > 1) {
                                      const unichar ls = [substring characterAtIndex:1];
                                      const int uc = ((hs - 0xd800) * 0x400) + (ls - 0xdc00) + 0x10000;
                                      if (0x1d000 <= uc && uc <= 0x1f77f) {
                                          returnValue = YES;
                                      }
                                  }
                              } else if (substring.length > 1) {
                                  const unichar ls = [substring characterAtIndex:1];
                                  if (ls == 0x20e3) {
                                      returnValue = YES;
                                  }
                              } else {
                                  if (0x2100 <= hs && hs <= 0x27ff) {
                                      returnValue = YES;
                                  } else if (0x2B05 <= hs && hs <= 0x2b07) {
                                      returnValue = YES;
                                  } else if (0x2934 <= hs && hs <= 0x2935) {
                                      returnValue = YES;
                                  } else if (0x3297 <= hs && hs <= 0x3299) {
                                      returnValue = YES;
                                  } else if (hs == 0xa9 || hs == 0xae || hs == 0x303d || hs == 0x3030 || hs == 0x2b55 || hs == 0x2b1c || hs == 0x2b1b || hs == 0x2b50) {
                                      returnValue = YES;
                                  }
                              }
                          }];
    
    return returnValue;
}


@end
